package de.mnit.schnipsel.zentral;

import de.mnit.basis.crypt.JavaBase64;
import de.mnit.basis.crypt.cipher.JAVA_CIPHER;
import de.mnit.basis.crypt.cipher.JavaCipher;
import de.mnit.basis.crypt.passwort.Passwort;
import de.mnit.basis.fehler.Fehler;
import de.mnit.basis.fehler.system.F_Sys_Sicherheit;
import de.mnit.basis.swt.dialog.Dialog_Passwort;
import de.mnit.basis.swt.dialog.SWT_Dialog;
import de.mnit.basis.sys.Ausgabe;
import de.mnit.basis.sys.sprache.S;
import de.mnit.schnipsel.db.DBManager;

/**
 * @author Michael Nitsche
 * 21.07.2010	Erstellt
 */
public class SC_Crypt {

	private static SC_Crypt instanz=null;
	private static final S s=new S(SC_Crypt.class);


	public static SC_Crypt i() {
		if(instanz==null)
			instanz=new SC_Crypt();
		return instanz;
	}


	public boolean gEingerichtet() {
		return DBManager.konfig().passAngelegt();
	}

	public static byte[] pass16(byte[] ba) {
		byte[] e=new byte[16];
		System.arraycopy(ba, 0, e, 0, ba.length);
		int c=0;
		for(int p=ba.length; p<e.length; p++)
			e[p]=(byte)c++;
		Ausgabe.debug(e);
		return e;
	}

	private byte[] dbpass=null;

	public byte[] sPass(String pass) {
		byte[] bapass=pass16(pass.getBytes());

		boolean passOk=DBManager.konfig().pruefeUserPass(bapass);
		if(!passOk) {
			SWT_Dialog.warnung(s.t("Das eingegebene Passwort ist falsch!"));
			return null;
		}
		return this.dbpass=DBManager.konfig().gibDBPass(bapass);
	}

	/** Gibt bei Fehlern null zurück! **/
	public byte[] gDBPass() {
		if(this.dbpass!=null)
			return dbpass;

		boolean angelegt=DBManager.konfig().passAngelegt();
		if(!angelegt) {
			SWT_Dialog.warnung(s.t("Bitte ein Passwort einrichten!"));
			return null;
		}

		Dialog_Passwort dp=new Dialog_Passwort();
		Passwort p=dp.gErgebnis(SC_GuiObs.i().hauptfenster());
		if(p==null)
			return null;

		String pass=dp.gRoh();
		return sPass(pass);
	}

	public String[] verschluesseln(String text, String format, boolean crypt_inhalt) throws F_Sys_Sicherheit {
		return new String[]{
			crypt_inhalt ? iVer(text)   : text,
			crypt_inhalt ? iVer(format) : format };
	}

	public String[] entschluesseln(String text, String format, boolean crypt_inhalt) throws F_Sys_Sicherheit {
		return new String[]{
			crypt_inhalt ? iEnt(text)   : text,
			crypt_inhalt ? iEnt(format) : format };
	}

	private String iVer(String text) throws F_Sys_Sicherheit {
		byte[] dbpass=gDBPass();
		if(dbpass==null)
			throw Fehler.sicherheit.da_Schluessel_Ungueltig();

		JavaCipher jc=new JavaCipher(JAVA_CIPHER.AES);
		byte[] erg=jc.verschluesseln(text.getBytes(), dbpass);
		String s= 'A'+JavaBase64.verschluesseln(erg);
		Ausgabe.debug(s);
		return s;
	}

	private String iEnt(String text) throws F_Sys_Sicherheit {
		SC_GuiObs.i().anzeige().sID(null);

		byte[] dbpass=gDBPass();
		if(dbpass==null)
			throw Fehler.sicherheit.da_Schluessel_Ungueltig();

		char version=text.charAt(0);
		if(version!='A')
			Fehler.sonstige.da_Verboten("Ungültiges Format: "+version, (int)version);

		text=text.substring(1);
		byte[] ba1=JavaBase64.entschluesseln(text);
		JavaCipher jc=new JavaCipher(JAVA_CIPHER.AES);
		byte[] ba2=jc.entschluesseln(ba1, dbpass);
		if(ba2==null)
			throw Fehler.sicherheit.da_Schluessel_Ungueltig();
		String s=new String(ba2);
		return s;
	}

}
